Odklenite moč WebCodecs! Celovit vodnik za dostop in manipulacijo podatkov video okvirjev z uporabo ravnin VideoFrame. Spoznajte formate slikovnih pik, postavitev pomnilnika in praktične primere uporabe za napredno obdelavo videa v brskalniku.
WebCodecs VideoFrame Plane: Poglobljen vpogled v dostop do podatkov video okvirja
WebCodecs predstavlja premik paradigme pri spletni obdelavi medijev. Zagotavlja nizkonivojski dostop do gradnikov medijev, kar razvijalcem omogoča ustvarjanje sofisticiranih aplikacij neposredno v brskalniku. Ena najmočnejših funkcij WebCodecs je objekt VideoFrame in znotraj njega ravnine VideoFrame, ki izpostavljajo surove slikovne podatke video okvirjev. Ta članek ponuja celovit vodnik za razumevanje in uporabo ravnin VideoFrame za napredno manipulacijo z videom.
Razumevanje objekta VideoFrame
Preden se poglobimo v ravnine, si na kratko poglejmo sam objekt VideoFrame. VideoFrame predstavlja en sam video okvir. Vsebuje dekodirane (ali kodirane) video podatke, skupaj s pripadajočimi metapodatki, kot so časovni žig, trajanje in informacije o formatu. API VideoFrame ponuja metode za:
- Branje podatkov slikovnih pik: Tu pridejo v poštev ravnine.
- Kopiranje okvirjev: Ustvarjanje novih objektov
VideoFrameiz obstoječih. - Zapiranje okvirjev: Sproščanje osnovnih virov, ki jih hrani okvir.
Objekt VideoFrame se ustvari med postopkom dekodiranja, običajno z VideoDecoder, ali ročno pri ustvarjanju okvirja po meri.
Kaj so ravnine VideoFrame?
Podatki slikovnih pik objekta VideoFrame so pogosto organizirani v več ravnin, zlasti v formatih, kot je YUV. Vsaka ravnina predstavlja drugačno komponento slike. Na primer, v formatu YUV420 so tri ravnine:
- Y (Luma): Predstavlja svetlost (luminanco) slike. Ta ravnina vsebuje informacije o sivinah.
- U (Cb): Predstavlja komponento krome za razliko modre barve.
- V (Cr): Predstavlja komponento krome za razliko rdeče barve.
Tudi formati RGB, čeprav na videz preprostejši, lahko v nekaterih primerih uporabljajo več ravnin. Število ravnin in njihov pomen sta v celoti odvisna od VideoPixelFormat objekta VideoFrame.
Prednost uporabe ravnin je v tem, da omogoča učinkovit dostop in manipulacijo specifičnih barvnih komponent. Na primer, morda želite prilagoditi samo luminanco (ravnina Y), ne da bi vplivali na barvo (ravnini U in V).
Dostopanje do ravnin VideoFrame: API
API VideoFrame ponuja naslednje metode za dostop do podatkov ravnin:
copyTo(destination, options): Kopira vsebino objektaVideoFramena cilj, ki je lahko drugVideoFrame,CanvasImageBitmapaliArrayBufferView. Objektoptionsnadzoruje, katere ravnine se kopirajo in kako. To je primarni mehanizem za dostop do ravnin.
Objekt options v metodi copyTo vam omogoča, da določite postavitev in cilj za podatke video okvirja. Ključne lastnosti vključujejo:
format: Želeni format slikovnih pik kopiranih podatkov. To je lahko enak format kot pri originalnemVideoFrameali drugačen format (npr. pretvorba iz YUV v RGB).codedWidthincodedHeight: Širina in višina video okvirja v slikovnih pikah.layout: Polje objektov, ki opisujejo postavitev vsake ravnine v pomnilniku. Vsak objekt v polju določa:offset: Odmik v bajtih od začetka podatkovnega medpomnilnika do začetka podatkov ravnine.stride: Število bajtov med začetkom vsake vrstice v ravnini. To je ključnega pomena za obravnavo polnjenja (padding).
Poglejmo si primer kopiranja VideoFrame v formatu YUV420 v surov medpomnilnik:
async function copyYUV420ToBuffer(videoFrame, buffer) {
const width = videoFrame.codedWidth;
const height = videoFrame.codedHeight;
// YUV420 ima 3 ravnine: Y, U in V
const yPlaneSize = width * height;
const uvPlaneSize = width * height / 4;
const layout = [
{ offset: 0, stride: width }, // Y ravnina
{ offset: yPlaneSize, stride: width / 2 }, // U ravnina
{ offset: yPlaneSize + uvPlaneSize, stride: width / 2 } // V ravnina
];
await videoFrame.copyTo(buffer, {
format: 'I420',
codedWidth: width,
codedHeight: height,
layout: layout
});
videoFrame.close(); // Pomembno je sprostiti vire
}
Razlaga:
- Izračunamo velikost vsake ravnine na podlagi
widthinheight. Y ima polno ločljivost, medtem ko sta U in V podvzorčena (4:2:0). - Polje
layoutdoloča postavitev pomnilnika.offsetdoloča, kje se vsaka ravnina začne v medpomnilniku,stridepa določa število bajtov za skok na naslednjo vrstico v tej ravnini. - Možnost
formatje nastavljena na 'I420', kar je pogost format YUV420. - Ključno je, da se po kopiranju pokliče
videoFrame.close(), da se sprostijo viri.
Formati slikovnih pik: Svet možnosti
Razumevanje formatov slikovnih pik je bistveno za delo z ravninami VideoFrame. VideoPixelFormat določa, kako so barvne informacije kodirane znotraj video okvirja. Tukaj je nekaj pogostih formatov slikovnih pik, s katerimi se lahko srečate:
- I420 (YUV420p): Planarni format YUV, kjer so komponente Y, U in V shranjene v ločenih ravninah. U in V sta podvzorčena za faktor 2 v vodoravni in navpični smeri. To je zelo pogost in učinkovit format.
- NV12 (YUV420sp): Pol-planarni format YUV, kjer je Y shranjen v eni ravnini, komponente U in V pa so prepletene v drugi ravnini.
- RGBA: Komponente rdeče, zelene, modre in alfa so shranjene v eni ravnini, običajno z 8 biti na komponento (32 bitov na slikovno piko). Vrstni red komponent se lahko razlikuje (npr. BGRA).
- RGB565: Komponente rdeče, zelene in modre so shranjene v eni ravnini s 5 biti za rdečo, 6 biti za zeleno in 5 biti za modro (16 bitov na slikovno piko).
- GRAYSCALE: Predstavlja sivinske slike z eno samo vrednostjo svetlosti (luma) za vsako slikovno piko.
Lastnost VideoFrame.format vam bo povedala format slikovnih pik določenega okvirja. Preverite to lastnost, preden poskusite dostopiti do ravnin. Za popoln seznam podprtih formatov si lahko ogledate specifikacijo WebCodecs.
Praktični primeri uporabe
Dostop do ravnin VideoFrame odpira širok spekter možnosti za napredno obdelavo videa v brskalniku. Tukaj je nekaj primerov:
1. Video učinki v realnem času
Video učinke v realnem času lahko uporabite z manipulacijo podatkov slikovnih pik v VideoFrame. Na primer, lahko bi implementirali sivinski filter tako, da bi povprečili komponente R, G in B vsake slikovne pike v okvirju RGBA in nato vse tri komponente nastavili na to povprečno vrednost. Ustvarite lahko tudi učinek sepije ali prilagodite svetlost in kontrast.
async function applyGrayscale(videoFrame) {
const width = videoFrame.codedWidth;
const height = videoFrame.codedHeight;
const buffer = new ArrayBuffer(width * height * 4); // RGBA
const rgba = new Uint8ClampedArray(buffer);
await videoFrame.copyTo(rgba, {
format: 'RGBA',
codedWidth: width,
codedHeight: height
});
for (let i = 0; i < rgba.length; i += 4) {
const r = rgba[i];
const g = rgba[i + 1];
const b = rgba[i + 2];
const gray = (r + g + b) / 3;
rgba[i] = gray; // Rdeča
rgba[i + 1] = gray; // Zelena
rgba[i + 2] = gray; // Modra
}
// Ustvarite nov VideoFrame iz spremenjenih podatkov.
const newFrame = new VideoFrame(rgba, {
format: 'RGBA',
codedWidth: width,
codedHeight: height,
timestamp: videoFrame.timestamp,
duration: videoFrame.duration
});
videoFrame.close(); // Sprostite originalni okvir
return newFrame;
}
2. Aplikacije računalniškega vida
Ravnine VideoFrame zagotavljajo neposreden dostop do podatkov slikovnih pik, potrebnih za naloge računalniškega vida. Te podatke lahko uporabite za implementacijo algoritmov za zaznavanje predmetov, prepoznavanje obrazov, sledenje gibanju in še več. Za dele kode, ki so kritični za zmogljivost, lahko uporabite WebAssembly.
Na primer, barvni VideoFrame lahko pretvorite v sivinskega in nato uporabite algoritem za zaznavanje robov (npr. Sobelov operator), da prepoznate robove na sliki. To bi lahko uporabili kot predprocesni korak za prepoznavanje predmetov.
3. Urejanje in sestavljanje videa
Ravnine VideoFrame lahko uporabite za implementacijo funkcij za urejanje videa, kot so obrezovanje, spreminjanje velikosti, vrtenje in sestavljanje. Z neposredno manipulacijo podatkov slikovnih pik lahko ustvarite prehode in učinke po meri.
Na primer, VideoFrame lahko obrežete tako, da v nov VideoFrame kopirate samo del podatkov slikovnih pik. Ustrezno bi prilagodili odmike in korake v layout.
4. Kodeki po meri in prekodiranje
Čeprav WebCodecs ponuja vgrajeno podporo za običajne kodeke, kot so AV1, VP9 in H.264, ga lahko uporabite tudi za implementacijo kodekov po meri ali cevovodov za prekodiranje. Postopek kodiranja in dekodiranja boste morali opraviti sami, vendar vam ravnine VideoFrame omogočajo dostop in manipulacijo surovih podatkov slikovnih pik. To bi lahko bilo uporabno za nišne video formate ali specializirane zahteve po kodiranju.
5. Napredna analitika
Z dostopom do osnovnih podatkov slikovnih pik lahko izvajate poglobljeno analizo video vsebine. To vključuje naloge, kot so merjenje povprečne svetlosti scene, prepoznavanje prevladujočih barv ali zaznavanje sprememb v vsebini scene. To lahko omogoči napredne aplikacije za video analitiko za varnost, nadzor ali analizo vsebine.
Delo s Canvas in WebGL
Čeprav lahko neposredno manipulirate s podatki slikovnih pik v ravninah VideoFrame, morate pogosto rezultat upodobiti na zaslonu. Vmesnik CanvasImageBitmap zagotavlja most med VideoFrame in elementom <canvas>. Iz VideoFrame lahko ustvarite CanvasImageBitmap in ga nato narišete na platno z metodo drawImage().
async function renderVideoFrameToCanvas(videoFrame, canvas) {
const bitmap = await createImageBitmap(videoFrame);
const ctx = canvas.getContext('2d');
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
bitmap.close(); // Sprostite vire bitne slike
videoFrame.close(); // Sprostite vire VideoFrame
}
Za naprednejše upodabljanje lahko uporabite WebGL. Podatke slikovnih pik iz ravnin VideoFrame lahko naložite v teksture WebGL in nato uporabite senčilnike za uporabo učinkov in transformacij. To vam omogoča, da za visoko zmogljivo obdelavo videa izkoristite grafično procesno enoto (GPU).
Premisleki o zmogljivosti
Delo s surovimi podatki slikovnih pik je lahko računsko intenzivno, zato je ključnega pomena upoštevati optimizacijo zmogljivosti. Tukaj je nekaj nasvetov:
- Zmanjšajte število kopij: Izogibajte se nepotrebnemu kopiranju podatkov slikovnih pik. Poskusite izvajati operacije na mestu, kadar koli je to mogoče.
- Uporabite WebAssembly: Za dele kode, ki so kritični za zmogljivost, razmislite o uporabi WebAssembly. WebAssembly lahko zagotovi skoraj naravno zmogljivost za računsko intenzivne naloge.
- Optimizirajte postavitev pomnilnika: Izberite pravi format slikovnih pik in postavitev pomnilnika za vašo aplikacijo. Razmislite o uporabi zgoščenih formatov (npr. RGBA), če ne potrebujete pogostega dostopa do posameznih barvnih komponent.
- Uporabite OffscreenCanvas: Za obdelavo v ozadju uporabite
OffscreenCanvas, da se izognete blokiranju glavne niti. - Profilirajte svojo kodo: Uporabite orodja za razvijalce v brskalniku, da profilirate svojo kodo in prepoznate ozka grla zmogljivosti.
Združljivost z brskalniki
WebCodecs in API VideoFrame so podprti v večini sodobnih brskalnikov, vključno s Chrome, Firefox in Safari. Vendar pa se lahko raven podpore razlikuje glede na različico brskalnika in operacijski sistem. Preverite najnovejše tabele združljivosti brskalnikov na spletnih mestih, kot je MDN Web Docs, da zagotovite, da so funkcije, ki jih uporabljate, podprte v vaših ciljnih brskalnikih. Za združljivost med brskalniki se priporoča zaznavanje funkcij.
Pogoste napake in odpravljanje težav
Tukaj je nekaj pogostih napak, ki se jim je treba izogibati pri delu z ravninami VideoFrame:
- Napačna postavitev: Zagotovite, da polje
layoutnatančno opisuje postavitev podatkov slikovnih pik v pomnilniku. Napačni odmiki ali koraki lahko povzročijo poškodovane slike. - Neujemajoči se formati slikovnih pik: Prepričajte se, da se format slikovnih pik, ki ga določite v metodi
copyTo, ujema z dejanskim formatomVideoFrame. - Uhajanje pomnilnika: Vedno zaprite objekte
VideoFrameinCanvasImageBitmap, ko končate z njimi, da sprostite osnovne vire. Če tega ne storite, lahko pride do uhajanja pomnilnika. - Asinhrone operacije: Ne pozabite, da je
copyToasinhrona operacija. Uporabiteawait, da zagotovite, da se operacija kopiranja zaključi, preden dostopite do podatkov slikovnih pik. - Varnostne omejitve: Zavedajte se varnostnih omejitev, ki se lahko uporabljajo pri dostopu do podatkov slikovnih pik iz videoposnetkov z drugega izvora.
Primer: Pretvorba YUV v RGB
Poglejmo si bolj zapleten primer: pretvorba VideoFrame YUV420 v VideoFrame RGB. To vključuje branje ravnin Y, U in V, njihovo pretvorbo v vrednosti RGB in nato ustvarjanje novega VideoFrame RGB.
To pretvorbo je mogoče implementirati z naslednjo formulo:
R = Y + 1.402 * (Cr - 128)
G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
B = Y + 1.772 * (Cb - 128)
Tukaj je koda:
async function convertYUV420ToRGBA(videoFrame) {
const width = videoFrame.codedWidth;
const height = videoFrame.codedHeight;
const yPlaneSize = width * height;
const uvPlaneSize = width * height / 4;
const yuvBuffer = new ArrayBuffer(yPlaneSize + 2 * uvPlaneSize);
const yuvPlanes = new Uint8ClampedArray(yuvBuffer);
const layout = [
{ offset: 0, stride: width }, // Y ravnina
{ offset: yPlaneSize, stride: width / 2 }, // U ravnina
{ offset: yPlaneSize + uvPlaneSize, stride: width / 2 } // V ravnina
];
await videoFrame.copyTo(yuvPlanes, {
format: 'I420',
codedWidth: width,
codedHeight: height,
layout: layout
});
const rgbaBuffer = new ArrayBuffer(width * height * 4);
const rgba = new Uint8ClampedArray(rgbaBuffer);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const yIndex = y * width + x;
const uIndex = Math.floor(y / 2) * (width / 2) + Math.floor(x / 2) + yPlaneSize;
const vIndex = Math.floor(y / 2) * (width / 2) + Math.floor(x / 2) + yPlaneSize + uvPlaneSize;
const Y = yuvPlanes[yIndex];
const U = yuvPlanes[uIndex] - 128;
const V = yuvPlanes[vIndex] - 128;
let R = Y + 1.402 * V;
let G = Y - 0.34414 * U - 0.71414 * V;
let B = Y + 1.772 * U;
R = Math.max(0, Math.min(255, R));
G = Math.max(0, Math.min(255, G));
B = Math.max(0, Math.min(255, B));
const rgbaIndex = y * width * 4 + x * 4;
rgba[rgbaIndex] = R;
rgba[rgbaIndex + 1] = G;
rgba[rgbaIndex + 2] = B;
rgba[rgbaIndex + 3] = 255; // Alfa
}
}
const newFrame = new VideoFrame(rgba, {
format: 'RGBA',
codedWidth: width,
codedHeight: height,
timestamp: videoFrame.timestamp,
duration: videoFrame.duration
});
videoFrame.close(); // Sprostite originalni okvir
return newFrame;
}
Ta primer prikazuje moč in zapletenost dela z ravninami VideoFrame. Zahteva dobro razumevanje formatov slikovnih pik, postavitve pomnilnika in pretvorb barvnih prostorov.
Zaključek
API za ravnine VideoFrame v WebCodecs odpira novo raven nadzora nad obdelavo videa v brskalniku. Z razumevanjem, kako neposredno dostopati do podatkov slikovnih pik in jih manipulirati, lahko ustvarite napredne aplikacije za video učinke v realnem času, računalniški vid, urejanje videa in še več. Čeprav je delo z ravninami VideoFrame lahko zahtevno, so potencialne koristi velike. Ker se WebCodecs še naprej razvija, bo nedvomno postal bistveno orodje za spletne razvijalce, ki delajo z mediji.
Spodbujamo vas, da eksperimentirate z API-jem za ravnine VideoFrame in raziščete njegove zmožnosti. Z razumevanjem osnovnih načel in uporabo najboljših praks lahko ustvarite inovativne in zmogljive video aplikacije, ki premikajo meje mogočega v brskalniku.
Dodatno učenje
- MDN Web Docs on WebCodecs
- WebCodecs Specification
- WebCodecs sample code repositories on GitHub.